import type { Card } from '@/types/card';

// 牌型枚举
export enum HandType {
  HIGH_CARD = 0,
  PAIR = 1,
  TWO_PAIR = 2,
  THREE_OF_A_KIND = 3,
  STRAIGHT = 4,
  FLUSH = 5,
  FULL_HOUSE = 6,
  FOUR_OF_A_KIND = 7,
  STRAIGHT_FLUSH = 8,
  ROYAL_FLUSH = 9
}

// 获取牌型文本
export function getHandTypeText(type: HandType): string {
  switch (type) {
    case HandType.HIGH_CARD: return '高牌';
    case HandType.PAIR: return '一对';
    case HandType.TWO_PAIR: return '两对';
    case HandType.THREE_OF_A_KIND: return '三条';
    case HandType.STRAIGHT: return '顺子';
    case HandType.FLUSH: return '同花';
    case HandType.FULL_HOUSE: return '葫芦';
    case HandType.FOUR_OF_A_KIND: return '四条';
    case HandType.STRAIGHT_FLUSH: return '同花顺';
    case HandType.ROYAL_FLUSH: return '皇家同花顺';
    default: return '未知';
  }
}

// 获取点数大小
export function getRankValue(rank: string): number {
  const values: Record<string, number> = {
    'TWO': 2, 'THREE': 3, 'FOUR': 4, 'FIVE': 5, 'SIX': 6, 'SEVEN': 7, 'EIGHT': 8, 'NINE': 9,
    'TEN': 10, 'JACK': 11, 'QUEEN': 12, 'KING': 13, 'ACE': 14
  };
  return values[rank] || 0;
}

// 判断是否为同花
const isFlush = (cards: Card[]): boolean => {
  if (cards.length !== 5) return false;
  const suit = cards[0].suit;
  return cards.every(card => card.suit === suit);
};

// 判断是否为顺子
const isStraight = (cards: Card[]): boolean => {
  if (cards.length !== 5) return false;
  const ranks = cards.map(card => getRankValue(card.rank)).sort((a, b) => a - b);
  
  // 检查普通顺子
  if (ranks[4] - ranks[0] === 4 && 
      ranks[1] - ranks[0] === 1 &&
      ranks[2] - ranks[1] === 1 &&
      ranks[3] - ranks[2] === 1 &&
      ranks[4] - ranks[3] === 1) {
    return true;
  }
  
  // 检查A2345顺子
  if (ranks.includes(14)) { // 如果有A
    const lowAceRanks = [...ranks.filter(r => r !== 14), 1].sort((a, b) => a - b);
    if (lowAceRanks[4] - lowAceRanks[0] === 4 &&
        lowAceRanks[1] - lowAceRanks[0] === 1 &&
        lowAceRanks[2] - lowAceRanks[1] === 1 &&
        lowAceRanks[3] - lowAceRanks[2] === 1 &&
        lowAceRanks[4] - lowAceRanks[3] === 1) {
      return true;
    }
  }
  
  return false;
};

// 判断是否为同花顺
const isStraightFlush = (cards: Card[]): boolean => {
  // 先判断是否为同花
  const suits = new Map<string, Card[]>();
  cards.forEach(card => {
    if (!suits.has(card.suit)) {
      suits.set(card.suit, []);
    }
    suits.get(card.suit)?.push(card);
  });

  // 检查是否有同花
  const flushCards = Array.from(suits.values())
    .find(sameSuitCards => sameSuitCards.length >= 5);

  if (!flushCards) {
    return false;
  }

  // 在同花中判断是否为顺子
  const values = flushCards
    .map(card => getRankValue(card.rank))
    .sort((a, b) => a - b);

  // 处理 A2345 的特殊情况
  if (values.includes(14)) { // 如果有A
    const lowAceValues = [...values.filter(v => v !== 14), 1].sort((a, b) => a - b);
    if (lowAceValues[4] - lowAceValues[0] === 4) {
      return true;
    }
  }

  // 处理普通顺子
  return values[4] - values[0] === 4 && values.length === 5;
};

// 判断是否为皇家同花顺
const isRoyalFlush = (cards: Card[]): boolean => {
  // 先判断是否为同花
  const suits = new Map<string, Card[]>();
  cards.forEach(card => {
    if (!suits.has(card.suit)) {
      suits.set(card.suit, []);
    }
    suits.get(card.suit)?.push(card);
  });

  // 检查是否有同花
  const flushCards = Array.from(suits.values())
    .find(sameSuitCards => sameSuitCards.length >= 5);

  if (!flushCards) {
    return false;
  }

  // 在同花中判断是否为皇家顺子
  const values = flushCards
    .map(card => getRankValue(card.rank))
    .sort((a, b) => a - b);

  // 检查是否包含 10、J、Q、K、A
  return values.includes(10) && 
         values.includes(11) && 
         values.includes(12) && 
         values.includes(13) && 
         values.includes(14);
};

// 获取牌型
export const getHandType = (cards: Card[]): HandType => {
  if (cards.length < 3) return HandType.HIGH_CARD;
  
  // 先判断是否为皇家同花顺
  if (isRoyalFlush(cards)) {
    return HandType.ROYAL_FLUSH;
  }

  // 再判断是否为同花顺
  if (isStraightFlush(cards)) {
    return HandType.STRAIGHT_FLUSH;
  }
  
  // 统计每个点数的数量
  const rankCounts = new Map<number, number>();
  cards.forEach(card => {
    const rankValue = getRankValue(card.rank);
    rankCounts.set(rankValue, (rankCounts.get(rankValue) || 0) + 1);
  });
  
  // 检查是否为四条
  if (Array.from(rankCounts.values()).includes(4)) {
    return HandType.FOUR_OF_A_KIND;
  }
  
  // 检查是否为葫芦
  if (Array.from(rankCounts.values()).includes(3) && Array.from(rankCounts.values()).includes(2)) {
    return HandType.FULL_HOUSE;
  }
  
  // 检查是否为同花
  if (cards.length === 5 && isFlush(cards)) {
    return HandType.FLUSH;
  }
  
  // 检查是否为顺子
  if (cards.length === 5 && isStraight(cards)) {
    return HandType.STRAIGHT;
  }
  
  // 检查是否为三条
  if (Array.from(rankCounts.values()).includes(3)) {
    return HandType.THREE_OF_A_KIND;
  }
  
  // 检查是否为两对
  const pairs = Array.from(rankCounts.values()).filter(count => count === 2);
  if (pairs.length >= 2) {
    return HandType.TWO_PAIR;
  }
  
  // 检查是否为一对
  if (pairs.length === 1) {
    return HandType.PAIR;
  }
  
  return HandType.HIGH_CARD;
};

// 评估牌型大小
export function evaluateHand(cards: Card[]): number {
  const type = getHandType(cards);
  const values = cards.map(card => getRankValue(card.rank));
  values.sort((a, b) => b - a);
  
  // 根据牌型计算分数
  let score = type * 1000000; // 牌型基础分
  
  // 统计每个点数的数量
  const rankCounts = new Map<number, number>();
  values.forEach(value => {
    rankCounts.set(value, (rankCounts.get(value) || 0) + 1);
  });
  
  // 按出现次数和大小排序
  const sortedRanks = Array.from(rankCounts.entries())
    .sort((a, b) => {
      if (a[1] !== b[1]) return b[1] - a[1];
      return b[0] - a[0];
    })
    .map(([rank]) => rank);
  
  switch (type) {
    case HandType.ROYAL_FLUSH:
      score += 14;
      break;
      
    case HandType.STRAIGHT_FLUSH:
    case HandType.STRAIGHT:
      // 对于A2345的情况特殊处理
      if (values.includes(14) && values.includes(2)) {
        score += 5; // A2345的顺子当作5点
      } else {
        score += Math.max(...values);
      }
      break;
      
    case HandType.FOUR_OF_A_KIND:
      // 四条的牌点数 * 100 + 单张的牌点数
      score += sortedRanks[0] * 100 + sortedRanks[1];
      break;
      
    case HandType.FULL_HOUSE:
      // 三条的牌点数 * 100 + 对子的牌点数
      score += sortedRanks[0] * 100 + sortedRanks[1];
      break;
      
    case HandType.FLUSH:
      // 同花按照每张牌的大小计算
      score += values.reduce((acc, val, idx) => acc + val * Math.pow(100, 4 - idx), 0);
      break;
      
    case HandType.THREE_OF_A_KIND:
      // 三条的牌点数 * 10000 + 第一张单牌 * 100 + 第二张单牌
      score += sortedRanks[0] * 10000 + sortedRanks[1] * 100 + sortedRanks[2];
      break;
      
    case HandType.TWO_PAIR:
      // 大对子点数 * 10000 + 小对子点数 * 100 + 单张点数
      score += sortedRanks[0] * 10000 + sortedRanks[1] * 100 + sortedRanks[2];
      break;
      
    case HandType.PAIR:
      // 对子点数 * 1000000 + 剩余牌点数按大小排序
      score += sortedRanks[0] * 1000000;
      for (let i = 1; i < sortedRanks.length; i++) {
        score += sortedRanks[i] * Math.pow(100, sortedRanks.length - i - 1);
      }
      break;
      
    case HandType.HIGH_CARD:
      // 每张牌按权重计算
      score += values.reduce((acc, val, idx) => acc + val * Math.pow(100, 4 - idx), 0);
      break;
  }
  
  return score;
}

// 生成组合
function generateCombinations<T>(arr: T[], r: number): T[][] {
  const result: T[][] = [];
  
  function combine(start: number, current: T[]) {
    if (current.length === r) {
      result.push([...current]);
      return;
    }
    
    for (let i = start; i < arr.length; i++) {
      current.push(arr[i]);
      combine(i + 1, current);
      current.pop();
    }
  }
  
  combine(0, []);
  return result;
}

// 获取所有可能的牌型组合
export const getPossibleHands = (cards: Card[]): Array<{ type: HandType; cards: Card[]; score: number }> => {
  const results: Array<{ type: HandType; cards: Card[]; score: number }> = [];
  
  // 按点数分组，忽略花色
  const rankGroups = new Map<number, Card[]>();
  cards.forEach(card => {
    const rankValue = getRankValue(card.rank);
    if (!rankGroups.has(rankValue)) {
      rankGroups.set(rankValue, []);
    }
    rankGroups.get(rankValue)?.push(card);
  });
  
  // 获取所有点数
  const ranks = Array.from(rankGroups.keys()).sort((a, b) => b - a);
  
  // 检查皇家同花顺
  const royalFlushCards = findRoyalFlush(cards);
  if (royalFlushCards) {
    results.push({
      type: HandType.ROYAL_FLUSH,
      cards: royalFlushCards,
      score: 1000
    });
  }
  
  // 检查同花顺
  const straightFlushCards = findStraightFlush(cards);
  if (straightFlushCards) {
    // 检查是否为 A2345 同花顺，确保 Ace 被正确选中
    const hasAce = straightFlushCards.some(card => card.rank === 'ACE');
    const hasTwo = straightFlushCards.some(card => card.rank === 'TWO');
    
    let score = 900;
    if (hasAce && hasTwo) {
      // A2345 同花顺
      score += 5;
    } else {
      // 普通同花顺
      score += Math.max(...straightFlushCards.map(card => getRankValue(card.rank)));
    }
    
    results.push({
      type: HandType.STRAIGHT_FLUSH,
      cards: straightFlushCards,
      score
    });
  }
  
  // 检查四条
  for (const [rankValue, sameRankCards] of rankGroups) {
    if (sameRankCards.length >= 4) {
      // 对于四条，我们只需要选择4张相同点数的牌
      results.push({
        type: HandType.FOUR_OF_A_KIND,
        cards: sameRankCards.slice(0, 4),
        score: 800 + rankValue
      });
    }
  }
  
  // 检查葫芦
  const fullHouseCombinations = findFullHouse(rankGroups);
  for (const fullHouseCards of fullHouseCombinations) {
    results.push({
      type: HandType.FULL_HOUSE,
      cards: fullHouseCards,
      score: 700 + getRankValue(fullHouseCards[0].rank)
    });
  }
  
  // 检查同花
  const flushCards = findFlush(cards);
  if (flushCards) {
    results.push({
      type: HandType.FLUSH,
      cards: flushCards,
      score: 600 + getRankValue(flushCards[0].rank)
    });
  }
  
  // 检查顺子
  const straightCards = findStraight(ranks);
  if (straightCards) {
    // 对于顺子，我们只需要选择5张连续点数的牌
    const straightRanks = straightCards.map(rank => rankGroups.get(rank)?.[0]).filter(Boolean) as Card[];
    results.push({
      type: HandType.STRAIGHT,
      cards: straightRanks,
      score: 500 + getRankValue(straightRanks[0].rank)
    });
  }
  
  // 检查三条
  for (const [rankValue, sameRankCards] of rankGroups) {
    if (sameRankCards.length >= 3) {
      // 对于三条，我们只需要选择3张相同点数的牌
      results.push({
        type: HandType.THREE_OF_A_KIND,
        cards: sameRankCards.slice(0, 3),
        score: 400 + rankValue
      });
    }
  }
  
  // 检查两对
  const twoPairCombinations = findTwoPair(rankGroups);
  for (const twoPairCards of twoPairCombinations) {
    results.push({
      type: HandType.TWO_PAIR,
      cards: twoPairCards,
      score: 300 + getRankValue(twoPairCards[0].rank)
    });
  }
  
  // 检查对子
  for (const [rankValue, sameRankCards] of rankGroups) {
    if (sameRankCards.length >= 2) {
      // 对于对子，我们只需要选择2张相同点数的牌
      results.push({
        type: HandType.PAIR,
        cards: sameRankCards.slice(0, 2),
        score: 200 + rankValue
      });
    }
  }
  
  // 检查高牌
  if (cards.length > 0) {
    // 对于高牌，我们只需要选择点数最大的牌
    const highCard = cards.reduce((max, card) => 
      getRankValue(card.rank) > getRankValue(max.rank) ? card : max
    );
    results.push({
      type: HandType.HIGH_CARD,
      cards: [highCard],
      score: 100 + getRankValue(highCard.rank)
    });
  }
  
  return results;
};

// 查找皇家同花顺
export const findRoyalFlush = (cards: Card[]): Card[] | null => {
  const suits = new Map<string, Card[]>();
  cards.forEach(card => {
    if (!suits.has(card.suit)) {
      suits.set(card.suit, []);
    }
    suits.get(card.suit)?.push(card);
  });
  
  for (const sameSuitCards of suits.values()) {
    const royalFlushCards = sameSuitCards.filter(card => 
      ['TEN', 'JACK', 'QUEEN', 'KING', 'ACE'].includes(card.rank)
    );
    if (royalFlushCards.length >= 5) {
      return royalFlushCards.slice(0, 5);
    }
  }
  return null;
};

// 查找同花顺
export const findStraightFlush = (cards: Card[]): Card[] | null => {
  // 按花色分组
  const suits = new Map<string, Card[]>();
  cards.forEach(card => {
    if (!suits.has(card.suit)) {
      suits.set(card.suit, []);
    }
    suits.get(card.suit)?.push(card);
  });

  // 对每个花色的牌进行判断
  for (const sameSuitCards of suits.values()) {
    if (sameSuitCards.length < 5) continue;

    // 获取该花色所有牌的点数并排序
    const values = sameSuitCards
      .map(card => getRankValue(card.rank))
      .sort((a, b) => a - b);

    // 处理 A2345 的特殊情况
    if (values.includes(14)) { // 如果有A
      const hasLowStraight = sameSuitCards.some(card => getRankValue(card.rank) === 2) &&
                            sameSuitCards.some(card => getRankValue(card.rank) === 3) &&
                            sameSuitCards.some(card => getRankValue(card.rank) === 4) &&
                            sameSuitCards.some(card => getRankValue(card.rank) === 5);
      
      if (hasLowStraight) {
        const aceCard = sameSuitCards.find(card => getRankValue(card.rank) === 14);
        const twoCard = sameSuitCards.find(card => getRankValue(card.rank) === 2);
        const threeCard = sameSuitCards.find(card => getRankValue(card.rank) === 3);
        const fourCard = sameSuitCards.find(card => getRankValue(card.rank) === 4);
        const fiveCard = sameSuitCards.find(card => getRankValue(card.rank) === 5);

        if (aceCard && twoCard && threeCard && fourCard && fiveCard) {
          return [aceCard, twoCard, threeCard, fourCard, fiveCard];
        }
      }
    }

    // 处理普通顺子
    for (let i = 0; i <= values.length - 5; i++) {
      if (values[i + 4] - values[i] === 4) {
        // 找到对应的牌
        const targetValues = values.slice(i, i + 5);
        const straightFlushCards = sameSuitCards
          .filter(card => targetValues.includes(getRankValue(card.rank)))
          .slice(0, 5);
        return straightFlushCards;
      }
    }
  }
  return null;
};

// 查找葫芦
const findFullHouse = (rankGroups: Map<number, Card[]>): Card[][] => {
  const results: Card[][] = [];
  const threeKinds: Card[][] = [];
  const pairs: Card[][] = [];
  
  // 收集所有可能的三条和对子
  for (const [_, sameRankCards] of rankGroups) {
    if (sameRankCards.length >= 3) {
      threeKinds.push(sameRankCards.slice(0, 3));
    }
    if (sameRankCards.length >= 2) {
      pairs.push(sameRankCards.slice(0, 2));
    }
  }
  
  // 组合所有可能的葫芦
  for (const threeKind of threeKinds) {
    for (const pair of pairs) {
      // 确保三条和对子不是同一个点数
      if (getRankValue(threeKind[0].rank) !== getRankValue(pair[0].rank)) {
        results.push([...threeKind, ...pair]);
      }
    }
  }
  
  return results;
};

// 查找同花
const findFlush = (cards: Card[]): Card[] | null => {
  const suits = new Map<string, Card[]>();
  cards.forEach(card => {
    if (!suits.has(card.suit)) {
      suits.set(card.suit, []);
    }
    suits.get(card.suit)?.push(card);
  });
  
  for (const sameSuitCards of suits.values()) {
    if (sameSuitCards.length >= 5) {
      return sameSuitCards.slice(0, 5);
    }
  }
  return null;
};

// 查找顺子
const findStraight = (ranks: number[]): number[] | null => {
  // 处理A-5顺子的特殊情况
  if (ranks.includes(14)) { // 如果有A
    const lowAceRanks = [...ranks.filter(r => r !== 14), 1].sort((a, b) => a - b);
    if (lowAceRanks[4] - lowAceRanks[0] === 4) {
      return lowAceRanks.slice(0, 5);
    }
  }
  
  // 处理普通顺子
  for (let i = 0; i <= ranks.length - 5; i++) {
    if (ranks[i] - ranks[i + 4] === 4) {
      return ranks.slice(i, i + 5);
    }
  }
  return null;
};

// 查找两对
const findTwoPair = (rankGroups: Map<number, Card[]>): Card[][] => {
  const results: Card[][] = [];
  const pairs: Card[][] = [];
  
  // 收集所有可能的对子
  for (const [_, sameRankCards] of rankGroups) {
    if (sameRankCards.length >= 2) {
      pairs.push(sameRankCards.slice(0, 2));
    }
  }
  
  // 组合所有可能的两对
  for (let i = 0; i < pairs.length; i++) {
    for (let j = i + 1; j < pairs.length; j++) {
      // 确保两个对子不是同一个点数
      if (getRankValue(pairs[i][0].rank) !== getRankValue(pairs[j][0].rank)) {
        results.push([...pairs[i], ...pairs[j]]);
      }
    }
  }
  
  return results;
};

// 验证配牌是否合法
export function validateHands(frontHand: Card[], middleHand: Card[], backHand: Card[]): boolean {
  // 检查牌数是否正确
  if (frontHand.length !== 3 || middleHand.length !== 5 || backHand.length !== 5) {
    return false;
  }

  // 检查是否有重复的牌
  const allCards = [...frontHand, ...middleHand, ...backHand];
  const cardSet = new Set(allCards.map(card => `${card.suit}-${card.rank}`));
  if (cardSet.size !== 13) {
    return false;
  }

  // 获取每个墩位的牌型和分数
  const backType = getHandType(backHand);
  const middleType = getHandType(middleHand);
  const frontType = getHandType(frontHand);

  // 如果牌型相同，比较分数
  if (backType === middleType) {
    const backScore = evaluateHand(backHand);
    const middleScore = evaluateHand(middleHand);
    if (backScore <= middleScore) {
      return false;
    }
  } else if (backType < middleType) { // 如果牌型不同，直接比较牌型大小
    return false;
  }

  if (middleType === frontType) {
    const middleScore = evaluateHand(middleHand);
    const frontScore = evaluateHand(frontHand);
    if (middleScore <= frontScore) {
      return false;
    }
  } else if (middleType < frontType) {
    return false;
  }

  return true;
} 